#include "hplcqinfinepumpprotocol.h"
#include "hplcqinfinepumpparsepacket.h"
#include "hplcqinfinepumpsendpacket.h"
#include "hplcqinfinepumpprotocoldata.h"
#include "hplcqinfinepumpsendsystempacket.h"
#include "hplcqinfinepumpparsesystempacket.h"
#include "common/hplcqinfinemakepacket.h"

#include "modulehplccmdid.h"
#include <QVariant>

namespace hplc
{
namespace qinfine
{

HplcQinfinePumpProtocol::HplcQinfinePumpProtocol(PumpParam &param, QObject *parent)
    : HplcQinfinePumpProtocol (*new HplcQinfinePumpProtocolData(), param, parent)
{

}

HplcQinfinePumpProtocol::HplcQinfinePumpProtocol(HplcQinfinePumpProtocolData &data, PumpParam &param, QObject *parent)
    : HplcQinfineProtocolCommon (data, param, parent)
    , m_param(&param)
{
    HplcQinfinePumpParsePacket *parser = new HplcQinfinePumpParsePacket(data, param, this);
    connect(parser, &BaseParsePacket::parseCompleted, this, &BaseProtocol::parseCompleted);
    HplcQinfinePumpSendPacket *sender = new HplcQinfinePumpSendPacket (data, this);
    connect(sender, &HplcQinfineSendCommonPacket::requestSend, this, &HplcQinfineProtocolCommon::requestSend);

    HplcQinfinePumpSendSystemPacket *systemSender = new HplcQinfinePumpSendSystemPacket(data);
    HplcQinfinePumpParseSystemPacket *systemParser = new HplcQinfinePumpParseSystemPacket(data, param);
    connect(systemParser, &HplcQinfinePumpParseSystemPacket::parseCompleted, this, &BaseProtocol::parseCompleted);

    data.m_parser = parser;
    data.m_sender = sender;
    data.m_systemParser = systemParser;
    data.m_systemSender = systemSender;
}

HplcQinfinePumpProtocol::~HplcQinfinePumpProtocol()
{
    HplcQinfinePumpProtocolData *d = static_cast<HplcQinfinePumpProtocolData*>(m_d);
    delete d->m_sender;
    delete d->m_parser;
    delete d->m_systemParser;
    delete d->m_systemSender;
}

bool HplcQinfinePumpProtocol::setProtocolCmd(int id, QVariant &var)
{
    switch (id)
    {
        // pump
        case hplc::PumpCmdID_SetFlow:
            getPumpSender()->setFlow(var.toFloat());
        break;
        case hplc::PumpCmdID_SetFlowPercent:
            getPumpSender()->setFlowPercent(var.toUInt());
        break;
        case hplc::PumpCmdID_SetPressureMin:
            getPumpSender()->setPressMin(var.toFloat());
        break;
        case hplc::PumpCmdID_SetPressureMax:
            getPumpSender()->setPressMax(var.toFloat());
        break;
        case hplc::PumpCmdID_SetPressureWarning:
            getPumpSender()->setPressWarning(var.toFloat());
        break;
        case hplc::PumpCmdID_SetStartStop:
            getPumpSender()->setStartStop(var.toUInt());
        break;
        case hplc::PumpCmdID_SetPauseRestore:
            getPumpSender()->setPauseRestore(var.toUInt());
        break;
        case hplc::PumpCmdID_SetPurge:
            getPumpSender()->setPurge(var.toUInt());
        break;
        case hplc::PumpCmdID_SetPurgeFlow:
            getPumpSender()->setPurgeFlow(var.toFloat());
        break;
        case hplc::PumpCmdID_SetPurgeTime:
            getPumpSender()->setPurgeTime(var.toUInt());
        break;
        case hplc::PumpCmdID_SetPressZero:
            getPumpSender()->setPressZero();
        break;
        case hplc::PumpCmdID_SetPressUploadFreq:
            getPumpSender()->setPressUploadFreq(var.toUInt());
        break;
        case hplc::PumpCmdID_SetFlowPressCompen:
            getPumpSender()->setPressCompen(var.toUInt());
        break;
        case hplc::PumpCmdID_SetMode:
            getPumpSender()->setMode(var.toUInt());
        break;
        case hplc::PumpCmdID_SetPressure:
            getPumpSender()->setPress(var.toFloat());
        break;
        case hplc::PumpCmdID_SetRunMode:
            getPumpSender()->setRunMode(var.toUInt());
        break;

        // pump system
        case hplc::PumpSystemCmdID_SetWorkModePressureCalib:
            getPumpSystemSender()->setWorkMode(hplc::PumpWorkMode_PressureCalib, var.toUInt());
        break;
        case hplc::PumpSystemCmdID_SetWorkModeRateCalib:
            getPumpSystemSender()->setWorkMode(hplc::PumpWorkMode_RateCalib, var.toUInt());
        break;
        case hplc::PumpSystemCmdID_SetWorkModePulseCompenCalib:
            getPumpSystemSender()->setWorkMode(hplc::PumpWorkMode_PulseCompenCalib, var.toUInt());
        break;
        case hplc::PumpSystemCmdID_SetWorkModeMotorCurrentCalib:
            getPumpSystemSender()->setWorkMode(hplc::PumpWorkMode_MotorCurrentCalib, var.toUInt());
        break;
        case hplc::PumpSystemCmdID_SetFlowCalibData:
            {
            getPumpSystemSender()->setFlowCalibDataCMD(1);
            QList<hplc::PumpRateCalibData> list;
            list = var.value<QList<hplc::PumpRateCalibData>>();
            foreach (auto var, list)
            {
                getPumpSystemSender()->setFlowCalibData(var.rpm, var.rate);
            }
            getPumpSystemSender()->setFlowCalibDataCMD(0);
            }
        break;
        case hplc::PumpSystemCmdID_SetFlowCalibLoadFlow:
            getPumpSystemSender()->setFlowCalibLoadFlow(var.toDouble());
        break;
        case hplc::PumpSystemCmdID_SetFlowCalibLoadRealFlow:
            getPumpSystemSender()->setFlowCalibLoadRealFlow(var.toDouble());
        break;
        case hplc::PumpSystemCmdID_SetFlowCalibLoadPress:
            getPumpSystemSender()->setFlowCalibLoadPress(var.toDouble());
        break;
        case hplc::PumpSystemCmdID_SetPressCalibData:
            {
            getPumpSystemSender()->setPressCalibDataCMD(1);
            QList<hplc::PumpPressureCalibData> list;
            list = var.value<QList<hplc::PumpPressureCalibData>>();
            foreach (auto var, list)
            {
                getPumpSystemSender()->setPressCalibData(var.adc, var.pressure);
            }
            getPumpSystemSender()->setPressCalibDataCMD(0);
            }
        break;
        case hplc::PumpSystemCmdID_SetPulseCompenCalibDataCmd:
            getPumpSystemSender()->setPulseCompenDataCMD(var.toUInt());
        break;
        case hplc::PumpSystemCmdID_SetPulseCompenCalibData:
            {
            getPumpSystemSender()->setPulseCompenDataCMD(1);
            QList<hplc::PumpPulseCompenCalibData> list;
            list = var.value<QList<hplc::PumpPulseCompenCalibData>>();
            foreach (auto var, list)
            {
                getPumpSystemSender()->setPulseCompenData(var.position, var.factor);
            }
            getPumpSystemSender()->setPulseCompenDataCMD(0);
            }
        break;
        case hplc::PumpSystemCmdID_SetPulseCompenDebugCmd:
            getPumpSystemSender()->setPulseCompenDebugCMD(var.toUInt());
        break;
        case hplc::PumpSystemCmdID_SetStepMotorIRun:
            getPumpSystemSender()->setStepMotorCurrentRun(var.toUInt());
        break;
        case hplc::PumpSystemCmdID_SetMotorCurrentCalibData:
            {
            getPumpSystemSender()->setMotorCurrentDataCMD(1);
            QList<hplc::PumpStepMotorCurrentCalibData> list;
            list = var.value<QList<hplc::PumpStepMotorCurrentCalibData>>();
            foreach (auto var, list)
            {
                getPumpSystemSender()->setMotorCurrentData(var.rpm, var.current);
            }
            getPumpSystemSender()->setMotorCurrentDataCMD(0);
            }
        break;

        default:
            return HplcQinfineProtocolCommon::setProtocolCmd(id, var);
        break;
    }
    return true;
}

bool HplcQinfinePumpProtocol::getProtocolCmd(int id, QVariant &var)
{
    switch (id)
    {
        // pump
        case hplc::PumpCmdID_GetFlow:
            getPumpSender()->getFlow();
        break;
        case hplc::PumpCmdID_GetFlowPercent:
            getPumpSender()->getFlowPercent();
        break;
        case hplc::PumpCmdID_GetPressureMin:
            getPumpSender()->getPressMin();
        break;
        case hplc::PumpCmdID_GetPressureMax:
            getPumpSender()->getPressMax();
        break;
        case hplc::PumpCmdID_GetPressureWarning:
            getPumpSender()->getPressWarning();
        break;
        case hplc::PumpCmdID_GetStartStop:
            getPumpSender()->getStartStop();
        break;
        case hplc::PumpCmdID_GetPauseRestore:
            getPumpSender()->getPauseRestore();
        break;
        case hplc::PumpCmdID_GetPurge:
            getPumpSender()->getPurge();
        break;
        case hplc::PumpCmdID_GetPurgeFlow:
            getPumpSender()->getPurgeFlow();
        break;
        case hplc::PumpCmdID_GetPurgeTime:
            getPumpSender()->getPurgeTime();
        break;
        case hplc::PumpCmdID_GetPressZero:
            getPumpSender()->getPressZeroVoltage();
        break;
        case hplc::PumpCmdID_GetPressUploadFreq:
            getPumpSender()->getPressUploadFreq();
        break;
        case hplc::PumpCmdID_GetFlowPressCompen:
            getPumpSender()->getPressCompen();
        break;
        case hplc::PumpCmdID_GetMode:
            getPumpSender()->getMode();
        break;
        case hplc::PumpCmdID_GetPressure:
            getPumpSender()->getPress();
        break;
        case hplc::PumpCmdID_GetRunMode:
            getPumpSender()->getRunMode();
        break;

        // pump system
        case hplc::PumpSystemCmdID_GetWorkMode:
            getPumpSystemSender()->getWorkMode();
        break;
        case hplc::PumpSystemCmdID_GetFlowCalibData:
            getPumpSystemSender()->getFlowCalibData();
        break;
        case hplc::PumpSystemCmdID_GetFlowCalibLoadFlow:
            getPumpSystemSender()->getFlowCalibLoadFlow();
        break;
        case hplc::PumpSystemCmdID_GetFlowCalibLoadRealFlow:
            getPumpSystemSender()->getFlowCalibLoadRealFlow();
        break;
        case hplc::PumpSystemCmdID_GetFlowCalibLoadPress:
            getPumpSystemSender()->getFlowCalibLoadPress();
        break;
        case hplc::PumpSystemCmdID_GetPressCalibData:
            getPumpSystemSender()->getPressCalibData();
        break;
        case hplc::PumpSystemCmdID_GetPulseCompenCalibData:
            getPumpSystemSender()->getPulseCompenData();
        break;
        case hplc::PumpSystemCmdID_GetStepMotorIRun:
            getPumpSystemSender()->getStepMotorCurrentRun();
        break;
        case hplc::PumpSystemCmdID_GetMotorCurrentCalibData:
            getPumpSystemSender()->getMotorCurrentData();
        break;
//	    case hplc::PumpSystemCmdID_GetMotorControlMode:
//			getPumpSystemSender()->getMotorC
//	    break;

        default:
            return HplcQinfineProtocolCommon::getProtocolCmd(id, var);
        break;
    }
    return true;
}

HplcQinfinePumpParsePacket *HplcQinfinePumpProtocol::getPumpParser()
{
    return static_cast<HplcQinfinePumpParsePacket*>(m_d->m_parser);
}

HplcQinfinePumpParseSystemPacket *HplcQinfinePumpProtocol::getPumpSystemParser()
{
    HplcQinfinePumpProtocolData *m_d = static_cast<HplcQinfinePumpProtocolData*>(this->m_d);
    return m_d->m_systemParser;
}

HplcQinfinePumpSendPacket *HplcQinfinePumpProtocol::getPumpSender()
{
    return static_cast<HplcQinfinePumpSendPacket*>(m_d->m_sender);
}

HplcQinfinePumpSendSystemPacket *HplcQinfinePumpProtocol::getPumpSystemSender()
{
    HplcQinfinePumpProtocolData *m_d = static_cast<HplcQinfinePumpProtocolData*>(this->m_d);
    return m_d->m_systemSender;
}

HplcQinfineSendCommonPacket *HplcQinfinePumpProtocol::getCommonSender()
{
    return static_cast<HplcQinfineSendCommonPacket*>(m_d->m_sender);
}

HplcQinfineSendCommonSystemPacket *HplcQinfinePumpProtocol::getCommonSystemSender()
{
    HplcQinfineProtocolCommonData *m_d = static_cast<HplcQinfineProtocolCommonData*>(this->m_d);
    return m_d->m_commonSystemSender;
}

void HplcQinfinePumpProtocol::setModel(quint8 model)
{
    m_param->deviceParam.model = static_cast<hplc::PumpModel>(model);

    QVariant var;
    var.setValue(m_param->deviceParam.model);
    emit parseCompleted(hplc::CommonSystemCmdID_SetModel, var);
}

} // qinfine
} // hplc

